package com.lzh.template.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzh.template.common.BaseResponse;
import com.lzh.template.common.ResultUtil;
import com.lzh.template.exception.LzhException;
import com.lzh.template.manager.AIManager;
import com.lzh.template.mapper.ChartMapper;
import com.lzh.template.model.dto.chart.AddChartDto;
import com.lzh.template.model.dto.chart.EditChartDto;
import com.lzh.template.model.dto.chart.GenChartByAIDto;
import com.lzh.template.model.dto.chart.QueryChartDto;
import com.lzh.template.model.entity.ChartEntity;
import com.lzh.template.model.vo.PageVo;
import com.lzh.template.model.vo.chart.GenChartVo;
import com.lzh.template.service.ChartService;
import com.lzh.template.utils.ExcelUtils;
import com.lzh.template.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Date;

/**
 * (LzhChart)表服务实现类
 *
 * @author luzhiheng
 * @since 2023-12-29 10:47:18
 */
@Service("chartService")
public class ChartServiceImpl extends ServiceImpl<ChartMapper, ChartEntity> implements ChartService {

    @Value("${modelId.chart-vue}")
    private Long modelId;

    @Resource
    private AIManager aiManager;

    @Override
    public BaseResponse<PageVo> queryChartPage(QueryChartDto dto) {
        Page<ChartEntity> page = new Page<>(dto.getCurrent(), dto.getPageSize());
        LambdaQueryWrapper<ChartEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(dto.getChartType()), ChartEntity::getChartType, dto.getChartType());
        queryWrapper.eq(StringUtils.isNotEmpty(dto.getCreateName()), ChartEntity::getCreateName, dto.getCreateName());
        queryWrapper.like(StringUtils.isNotEmpty(dto.getGoal()), ChartEntity::getGoal, dto.getGoal());
        queryWrapper.like(StringUtils.isNotEmpty(dto.getName()), ChartEntity::getName, dto.getName());
        this.page(page, queryWrapper);
        PageVo<ChartEntity> pageVo = new PageVo<>(page.getTotal(), page.getRecords());
        return ResultUtil.success(pageVo);
    }

    @Override
    public void addChart(AddChartDto dto) {
        ChartEntity chartEntity = new ChartEntity(dto);
        this.save(chartEntity);
    }

    @Override
    public void deleteChart(Long id) {
        this.removeById(id);
    }

    @Override
    public void editChart(EditChartDto dto) {
        ChartEntity chartEntity = this.getById(dto.getId());
        if (chartEntity == null) {
            throw new LzhException("图表数据不存在");
        }
        chartEntity.setChartData(dto.getChartData());
        chartEntity.setChartType(dto.getChartType());
        chartEntity.setGoal(dto.getGoal());
        this.updateById(chartEntity);
    }

    @Override
    public BaseResponse<GenChartVo> genChartByAI(MultipartFile file, GenChartByAIDto dto) {

        String name = dto.getName();
        String chartType = dto.getChartType();

//        final String prompt = "你是一个数据分析师和前端开发专家，接下来我会按照以下固定格式给你提供内容：\n" +
//                "分析需求：\n" +
//                "{数据分析的需求或者目标}\n" +
//                "原始数据：\n" +
//                "{csv格式的原始数据，用,作为分隔符}\n" +
//                "请根据这两部分内容，按照以下指定格式生成内容（此外不要输出任何多余的开头、结尾、注释）\n" +
//                "【【【【【\n" +
//                "{前端 Echarts V5 的 option 配置对象js代码，合理地将数据进行可视化，不要生成任何多余的内容，比如注释}\n" +
//                "【【【【【\n" +
//                "{明确的数据分析结论、越详细越好，不要生成多余的注释}";

        StringBuilder userInput = new StringBuilder();
        userInput.append("你是一个数据分析师，接下来我会给你我的分析目标和原始数据，请告诉我分析结论。").append("\n");
        String goal = dto.getGoal();
        userInput.append("分析需求：").append("\n");
        userInput.append(goal);
        if (StringUtils.isNotBlank(chartType)) {
            userInput.append("，请使用").append(chartType).append("\n");
        } else {
            userInput.append("\n");
        }
        userInput.append("原始数据：").append("\n");
        String csvData = ExcelUtils.excelToCsv(file);
        userInput.append(csvData).append("\n");

        String answer = aiManager.doChat(modelId, userInput.toString());
        String[] split = answer.split("【【【【【");
        if (split.length < 3) {
            throw new LzhException("AI生成错误");
        }
        String chartCode = split[1].trim();
        String analyze = split[2].trim();

        // 插入到数据库
        ChartEntity chartEntity = new ChartEntity();
        chartEntity.setName(name);
        chartEntity.setGoal(goal);
        chartEntity.setChartData(csvData);
        chartEntity.setChartType(chartType);
        chartEntity.setGenChart(chartCode);
        chartEntity.setGenResult(analyze);
        chartEntity.setCreateTime(new Date());
        chartEntity.setCreateName(SecurityUtils.getUsername());
        boolean save = this.save(chartEntity);
        if (!save) {
            throw new LzhException("图表保存失败");
        }

        GenChartVo genChartVo = new GenChartVo(chartCode, analyze);
        return ResultUtil.success(genChartVo);
    }
}